package cn.memset.code.parallel;

import java.util.*;
import java.util.stream.Collectors;

public class OrderExample {
    public static void main(String[] args) {
        unorderedExample();
    }

    public static void forEachExample() {
        ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));

        System.out.println("===forEach====");

        // 在并行流中， forEach 方法是无视 Stream 的 encounter order 的
        list.parallelStream().forEach(i -> {
            System.out.println(i + "：thread-" + Thread.currentThread().getName());
        });

        System.out.println("===forEachOrdered====");

        // 在并行流中， forEachOrdered 方法可以保持 encounter order
        list.parallelStream().forEachOrdered(i -> {
            System.out.println(i + "：thread-" + Thread.currentThread().getName());
        });
    }

    public static void unorderedExample() {
        // 我们用 TreeMap 来做实验，因为 ArrayList 的特殊性，很难展示 unordered 的性质

        // TreeSet 中的元素是按从小到大排序的，即 [-7, -3, 1, 5, 12]
        TreeSet<Integer> set = new TreeSet<>(Arrays.asList(1, 12, 5, -7, -3));

        // 按 encounter order 打印 set，输出为
        System.out.println("The encounter order of set: ");
        set.stream().forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();

        // TreeSet 是有序的，所以来自 TreeSet 的 Stream 也是有序的
        // 当 Stream 是有序时，执行操作 limit(2) ，不管是串行还是并行，也不管执行多少次，结果都是前两位数字 [-7, -3]
        System.out.println("Limit ordered Stream: ");
        set.stream().parallel().limit(2).forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();
        set.stream().parallel().limit(2).forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();
        set.stream().parallel().limit(2).forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();
        set.stream().parallel().limit(2).forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();

        // 我们使用 unordered 方法将 Stream 转换为无序的
        // 当 Stream 是无序时，并行执行操作 limit(2) ，会发现执行多次时，输出的数字是不一样的（不确定性）
        System.out.println("Limit unordered Stream: ");
        System.out.print("first time: ");
        set.stream().unordered().parallel().limit(2).forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();
        System.out.print("second time: ");
        set.stream().unordered().parallel().limit(2).forEachOrdered(s -> System.out.print(s + " "));
        System.out.println();
    }
}
